﻿/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Telnet UI Application
 * Version 2.10
 * 
 * Connection Definition Class
 *      Represents and manages a user connection definition.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.IO;
using System.Net;
using System.Drawing;
using Adaptive.Foundation;
using Adaptive.Foundation.IO;
using Adaptive.Network;
using Adaptive.Network.Sockets;

namespace Adaptive.Telnet.UI
{
    /// <summary>
    /// Represents and manages a user connection definition.
    /// </summary>
    public sealed class ConnectionDefinition : AiObjectBase 
    {
        /*--------------------------------------------------------------------------------
         * Public Event Definitions
         *------------------------------------------------------------------------------*/
        #region Public Event Definitions
        #endregion

        /*--------------------------------------------------------------------------------
         * Private Constants Declarations
         *------------------------------------------------------------------------------*/
        #region Private Constants Declarations
        #endregion

        /*--------------------------------------------------------------------------------
         * Private Member Declarations
         *------------------------------------------------------------------------------*/
        #region Private Member Declarations

        private DomainEndPoint _remoteEndPoint;
        private Font _font;
        private string _description;
        private bool _sendAsTyped;

        #endregion

        /*--------------------------------------------------------------------------------
         * Constructor / Dispose / Destructor Methods
         *------------------------------------------------------------------------------*/
        #region Constructor / Dispose / Destructor Methods
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <remarks>
        /// This is the default constructor.
        /// </remarks>
        public ConnectionDefinition()
            : base()
        {
            _remoteEndPoint = new DomainEndPoint();
            _font = new Font("Courier New", 8.25f, FontStyle.Regular);
            _description = string.Empty;
            _sendAsTyped = true;
        }
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="name">The name assigned to the definition.</param>
        /// <param name="address">A domain name or IP address value to connect to.</param>
        /// <param name="port">The internet port number.</param>
        public ConnectionDefinition(string name, string address, short port) : base()
        {
            Name = name;
            _remoteEndPoint = new DomainEndPoint(address, port);
            _font = new Font("Courier New", 8.25f, FontStyle.Regular);
            _description = string.Empty;
            _sendAsTyped = true;
        }
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="name">The name assigned to the definition.</param>
        /// <param name="address">A domain name or IP address value to connect to.</param>
        /// <param name="port">The internet port number.</param>
        /// <param name="description">A description for the connection definition.</param>
        public ConnectionDefinition(string name, string address, short port, string description)
            : base()
        {
            Name = name;
            _remoteEndPoint = new DomainEndPoint(address, port);
            _font = new Font("Courier New", 8.25f, FontStyle.Regular);
            _description = description;
            _sendAsTyped = true;
        }
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="name">The name assigned to the definition.</param>
        /// <param name="endPoint">An <see cref="IPEndPoint"/> instance defininig the remote end point.</param>
        public ConnectionDefinition(string name, IPEndPoint endPoint)
            : base()
        {
            Name = name;
            _remoteEndPoint = new DomainEndPoint(endPoint.Address.ToString(), (short)endPoint.Port);
            _font = new Font("Courier New", 8.25f, FontStyle.Regular);
            _description = string.Empty;
            _sendAsTyped = true;
        }
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="name">The name assigned to the definition.</param>
        /// <param name="endPoint">An <see cref="IPEndPoint"/> instance defininig the remote end point.</param>
        /// <param name="description">A description for the connection definition.</param>
        public ConnectionDefinition(string name, IPEndPoint endPoint, string description)
            : base()
        {
            Name = name;
            _remoteEndPoint = new DomainEndPoint(endPoint.Address, (short)endPoint.Port);
            _font = new Font("Courier New", 8.25f, FontStyle.Regular);
            _description = description;
            _sendAsTyped = true;
        }
        /// <summary>
        /// Deallocates internally allocated objects.
        /// </summary>
        /// <param name="disposing">
        /// A value indicating whether the object is being disposed.
        /// </param>
        protected override void Dispose(bool disposing)
        {
            if ((!Disposed) && (disposing))
            {
                if (_font != null)
                    _font.Dispose();
            }

            _font = null;
            _remoteEndPoint = null;
            _description = null;
            base.Dispose(disposing);
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Properties
         *------------------------------------------------------------------------------*/
        #region Public Properties
        /// <summary>
        /// Gets or sets a description to be associated with the connection.
        /// </summary>
        /// <value>
        /// A description string.
        /// </value>
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }
        /// <summary>
        /// Gets or sets the font to use for the text display when connected.
        /// </summary>
        /// <value>
        /// A <see cref="Font"/> object instance.
        /// </value>
        public Font Font
        {
            get { return _font; }
            set { _font = value; }
        }
        /// <summary>
        /// Gets the reference to the remote end point definition.
        /// </summary>
        /// <value>
        /// A <see cref="DomainEndPoint"/> instance containing the remote address.
        /// </value>
        public DomainEndPoint RemoteEndPoint
        {
            get { return _remoteEndPoint; }
        }
        /// <summary>
        /// Gets or sets a value indicating whether to send characters as they are typed.
        /// </summary>
        /// <value>
        /// <b>true</b> to send characters as they are typed; or <b>false</b> to wait to send
        /// until <b>Enter</b> is pressed.
        /// </value>
        public bool SendAsTyped
        {
            get { return _sendAsTyped; }
            set { _sendAsTyped = value; }
        }

        #endregion

        /*--------------------------------------------------------------------------------
         * Protected Methods / Event Methods
         *------------------------------------------------------------------------------*/
        #region Protected Methods / Event Methods
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Clears the contents of the object instance without disposing of the instance.
        /// </summary>
        public override void Clear()
        {
            _description = string.Empty;
            _sendAsTyped = true;
            if (_font != null)
                _font.Dispose();
            _font = new Font("Courier New", 8.25f, FontStyle.Regular);
            _remoteEndPoint = null;
            _remoteEndPoint = new DomainEndPoint();
        }
        /// <summary>
        /// Attempts to load the data definition from an input source.
        /// </summary>
        /// <param name="inputStream">The input stream instance.</param>
        public void Load(Stream inputStream)
        {
            BinaryReader reader = null;

            //Create the reader.
            try
            {
                reader = new BinaryReader(inputStream);
            }
            catch
            {
                reader = null;
            }
            if (reader != null)
            {
                string fontName = string.Empty;
                float fontSize = 0;
                FontStyle style = FontStyle.Regular;

                //Read the name, description, and flags.
                Name = reader.ReadString();
                _description = reader.ReadString();
                _sendAsTyped = reader.ReadBoolean();
                
                //Read the address definition.
                string domain = reader.ReadString();
                _remoteEndPoint.Address = IPAddress.Parse(reader.ReadString());
                _remoteEndPoint.Port = reader.ReadInt32();
                _remoteEndPoint.DomainName = domain;

                //Read the font definition.
                fontName = reader.ReadString();
                fontSize = reader.ReadSingle();
                style = (FontStyle)reader.ReadInt32();
                _font = new Font(fontName, fontSize, style);

            }
            reader = null;
        }
        /// <summary>
        /// Attempts to write the data definition to an output source.
        /// </summary>
        /// <param name="outputStream">The output stream instance.</param>
        public void Save(Stream outputStream)
        {
            BinaryWriter writer = null;

            //Create the writer.
            try
            {
                writer = new BinaryWriter(outputStream);
            }
            catch
            {
                writer = null;
            }
            if (writer != null)
            {
                //Write the name, description and flags.
                writer.Write(Name);
                writer.Write(_description);
                writer.Write(_sendAsTyped);
                
                //Write the Address data.
                writer.Write(_remoteEndPoint.DomainName);
                writer.Write(_remoteEndPoint.Address.ToString());
                writer.Write(_remoteEndPoint.Port);

                //Write the font definition.
                writer.Write(_font.FontFamily.Name);
                writer.Write(_font.Size);
                writer.Write((int)Font.Style);

            }
            writer = null;
        }

        #endregion

        /*--------------------------------------------------------------------------------
         * Private Event Handlers
         *------------------------------------------------------------------------------*/
        #region Private Event Handlers
        #endregion

        /*--------------------------------------------------------------------------------
         * Private Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Private Methods / Functions
        #endregion

    }
}
